package com.xomily.web.core.config;

import com.alibaba.fastjson.JSONObject;
import com.xomily.common.utils.ServletUtils;
import com.xomily.common.utils.ip.IpUtils;
import com.xomily.common.utils.uuid.IdUtils;
import com.xomily.devops.domain.DevAlarmLog;
import com.xomily.devops.service.IDevAlarmLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author zhongshiyu
 * @date 2025/4/6
 */
@Component
@Slf4j
public class SqlInjectionFilter extends OncePerRequestFilter {
//    @Resource
//    private IDevAlarmLogService alarmLogService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 创建一个包装器来获取请求参数
        HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(request) {
            @Override
            public String getParameter(String name) {
                String value = super.getParameter(name);
                return sanitizeInput(value);
            }

            @Override
            public String[] getParameterValues(String name) {
                String[] values = super.getParameterValues(name);
                if (values != null) {
                    for (int i = 0; i < values.length; i++) {
                        values[i] = sanitizeInput(values[i]);
                    }
                }
                return values;
            }
        };

        // 继续过滤链
        filterChain.doFilter(requestWrapper, response);
    }

    private String sanitizeInput(String input) {
        if (input == null) {
            return null;
        }
        // 在这里实现 SQL 注入检测逻辑
        // 例如，检查输入中是否存在潜在的 SQL 注入字符
        if (containsSqlInjection(input)) {
            DevAlarmLog devAlarmLog = new DevAlarmLog();
            String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
            devAlarmLog.setIp(ip);
            devAlarmLog.setType("SqlInjection");
            devAlarmLog.setCode(IdUtils.fastUUID());
            devAlarmLog.setContent("SQL 注入检测到潜在的攻击，请求已被阻止。");
            System.err.println("SQL 注入检测到潜在的攻击，请求已被阻止。,{}"+ JSONObject.toJSONString(devAlarmLog));
//            alarmLogService.insertDevAlarmLog(devAlarmLog);
            throw new SecurityException("SQL 注入检测到潜在的攻击，请求已被阻止。");
        }
        return input;
    }

    private boolean containsSqlInjection(String input) {
        // 在这里实现具体的 SQL 注入检测逻辑
        // 以下是一些常见的 SQL 注入模式
        String[] sqlInjections = {"'", "--", ";", "OR 1=1", "UNION SELECT", "DROP", "ALTER", "CREATE", "EXEC", "TRUNCATE",
                "INSERT", "UPDATE", "DELETE", "DECLARE", "/*", "*/", "@@", "@", "CHAR", "NCHAR", "VARCHAR", "NVARCHAR",
                "SELECT", "FROM", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", "OFFSET", "HAVING", "INNER JOIN", "LEFT JOIN",
                "RIGHT JOIN", "FULL OUTER JOIN", "UNION ALL", "INTERSECT", "EXCEPT"};
        for (String injection : sqlInjections) {
            if (input.toUpperCase().contains(injection.toUpperCase())) {
                return true;
            }
        }
        return false;
    }
}